package main

import (
	"fmt"
	"strings"
)

// 函数

func init() {
	fmt.Println("这是一个初始化函数，在导入这个包的时候都会被执行")
}

func sayHello() {
	fmt.Println("hello world!")
}

func intSum(a, b int) int {
	ret := a + b
	return ret
}

func calc(x, y int) (sum, sub int) {
	sum = x + y
	sub = x - y
	return
}
func add(x, y int) int {
	return x + y
}

func sub(x, y int) int {
	return x - y
}

func calcAgain(x, y int, op func(int, int) int) int {
	return op(x, y)
}

// 定义一个函数，它的返回值也是一个函数
func adder() func(int) int {
	var x int
	return func(y int) int {
		x += y
		return x
	}
}

func makeSuffixFunc(suffix string) func(string) string {
	return func(name string) string {
		if !strings.HasSuffix(name, suffix) {
			return name + suffix
		}
		return name
	}
}

func CanChangeSum(args ...int) int {
	_sum := 0
	for _, arg := range args {
		_sum += arg
	}
	return _sum
}

func main() {
	// 1. 不带参数
	sayHello()

	// 2. 带参数以及单返回值
	res := intSum(10, 20)
	fmt.Println(res)

	// 3. 多返回值
	m, n := calc(10, 20)
	fmt.Println(m, n)

	// 4. 参数作为参数
	r1 := calcAgain(10, 20, add)
	r2 := calcAgain(10, 20, sub)
	fmt.Println(r1) // 30
	fmt.Println(r2) // -10

	// 5. 匿名函数:
	// 5.1 将匿名函数保存到变量
	add := func(x, y int) {
		fmt.Println(x + y)
	}
	add(10, 20) // 30
	// 5.2 自执行函数：匿名函数定义完加()直接执行
	func(x, y int) {
		fmt.Println(x + y)
	}(10, 20)

	// 6. 闭包
	var f = adder()
	fmt.Println(f(10)) // 10
	fmt.Println(f(20)) // 30
	fmt.Println(f(30)) // 60
	// 6.1 进阶一
	jpgFunc := makeSuffixFunc(".jpg")
	txtFunc := makeSuffixFunc(".txt")
	fmt.Println(jpgFunc("test")) //test.jpg
	fmt.Println(txtFunc("test")) //test.txt

	// 7. 可变参数 == 切片
	fmt.Println("可变参数结果:", CanChangeSum(10, 20, 30, 40, 50)) // 150
	var mySlice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	fmt.Println("可变参数传递数组或切片:", CanChangeSum(mySlice...)) // 55
}
